package photoEffects
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.BlendMode;
	import flash.display.GradientType;
	import flash.display.Shader;
	import flash.display.Shape;
	import flash.filters.BlurFilter;
	import flash.filters.ShaderFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	import org.casalib.events.ProcessEvent;

	public class PinHoleCameraEffect extends PhotoEffect
	{
		/**
		 * Constructor
		 */
		public function PinHoleCameraEffect()
		{
			super();
		}
		
		public static const NAME:String = "Pin Hole Camera";
		
		/**
		 * Apply the effect on a Bitmap. When the apply is finished, a ProcessEvent.COMPLETE is dispatched.
		 * @param bitmap The source Bitmap.
		 * @param callBack A function that accept a Bitmap object. Called when apply is finished.
		 */
		public override function applyOn(bitmap:Bitmap, callBack:Function = null):void
		{
			_workingBitmap = new Bitmap(bitmap.bitmapData.clone());

			var s:Shader = new Shader(new ShaderClass_sepia() as ByteArray);
			s.data.intensity.value = [0.15];
			shaderFilter_sepia = new ShaderFilter(s);
			
			_workingBitmap.bitmapData.applyFilter(_workingBitmap.bitmapData,_workingBitmap.getBounds(_workingBitmap),new Point(),shaderFilter_sepia);
			
			
			/* Apply blur corners */
			var blurImg:BitmapData = _workingBitmap.bitmapData.clone();
			blurImg.applyFilter(blurImg,blurImg.rect,new Point(),new BlurFilter(5,5,3));
			
			var alphaShape:Shape = new Shape();
			var box:Matrix = new Matrix();
			box.createGradientBox(blurImg.width, blurImg.height);
			alphaShape.graphics.beginGradientFill(GradientType.RADIAL,[0x000000,0x000000],[0,1],[0,255],box);
			alphaShape.graphics.drawRect(0,0,blurImg.width,blurImg.height);
			alphaShape.graphics.endFill();
			alphaShape.cacheAsBitmap = true;
			
			var gradientBitmap:BitmapData = new BitmapData(alphaShape.width, alphaShape.height, true, 0 );
			gradientBitmap.draw(alphaShape);
			
			blurImg.copyChannel(gradientBitmap, gradientBitmap.rect, new Point(), BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA);
			
			_workingBitmap.bitmapData.draw(blurImg);
			
			
			/* Apply dark corners */
			alphaShape.graphics.clear();
			alphaShape.graphics.beginGradientFill(GradientType.RADIAL,[0x000000,0x000000],[0,0.25],[0,255],box);
			alphaShape.graphics.drawRect(0,0,blurImg.width,blurImg.height);
			alphaShape.graphics.endFill();
			alphaShape.cacheAsBitmap = true;
			
			_workingBitmap.bitmapData.draw(alphaShape,null,null,BlendMode.MULTIPLY,null,true);
			_workingBitmap.bitmapData.draw(_workingBitmap.bitmapData,null,null,BlendMode.MULTIPLY,null,true);
			
			
			_resultBitmap = _workingBitmap;
			_workingBitmap = null;
			gradientBitmap.dispose();
			
			dispatchEvent(new ProcessEvent(ProcessEvent.COMPLETE));
			
			if(callBack != null){
				callBack(_resultBitmap);
			}
		}
		
		[Embed(source="../../pb/sepia.pbj", mimeType="application/octet-stream")]
		private static var ShaderClass_sepia:Class;
		private var shaderFilter_sepia:ShaderFilter;
	}
}